﻿#region Namespace References

using System;
using System.Collections.Generic;

#endregion

namespace DynConDevCorp.OpenArch.SmartData.Persistance
{
    /// <summary>
    /// 
    /// </summary>
    public class SmartLoaderSettings
    {
        #region Public Instance Methods

        /// <summary>
        /// Gets the meta entity.
        /// </summary>
        /// <param name="entityType">Type of the entity.</param>
        /// <returns></returns>
        public PersistanceMetadata GetMetaEntity(Type entityType)
        {
            PersistanceMetadata retVal;
            if (!m_MetaEntityLookup.TryGetValue(entityType, out retVal))
            {
                retVal = PersistanceMetadataManager.GlobalInstance.GetMetadata(entityType);
                SetMetaEntity(entityType, retVal);
            }
            return retVal;
        }

        /// <summary>
        /// Gets the relationships.
        /// </summary>
        /// <param name="entityType">Type of the entity.</param>
        /// <returns></returns>
        public RelationshipList GetRelationships(Type entityType)
        {
            RelationshipList retVal;
            if (!m_RelationshipLookup.TryGetValue(entityType, out retVal))
            {
                retVal = new RelationshipList();
                m_RelationshipLookup.Add(entityType, retVal);
            }
            return retVal;
        }

        /// <summary>
        /// Gets the name of the table.
        /// </summary>
        /// <param name="entityType">Type of the entity.</param>
        /// <returns></returns>
        public string GetTableName(Type entityType)
        {
            return m_TableNameLookup[entityType];
        }

        /// <summary>
        /// Registers the specified child key field.
        /// </summary>
        /// <typeparam name="TChild">The type of the child.</typeparam>
        /// <typeparam name="TParent">The type of the parent.</typeparam>
        /// <param name="childKeyField">The child key field.</param>
        /// <param name="parentKeyField">The parent key field.</param>
        /// <param name="childReferenceField">The child reference field.</param>
        public void Register<TChild, TParent>(string childKeyField, string parentKeyField, string childReferenceField)
        {
            Relationship relationship = new Relationship();
            relationship.ChildType = typeof (TChild);
            relationship.ChildKeyField = childKeyField;
            relationship.ParentType = typeof (TParent);
            relationship.ParentKeyField = parentKeyField;
            relationship.ChildReferenceField = childReferenceField;
            RelationshipList relationshipList;
            if (!m_RelationshipLookup.TryGetValue(typeof (TChild), out relationshipList))
            {
                relationshipList = new RelationshipList();
                m_RelationshipLookup.Add(typeof (TChild), relationshipList);
            }
            relationshipList.Add(relationship);
        }

        /// <summary>
        /// Registers the specified table name.
        /// </summary>
        /// <typeparam name="TEntity">The type of the entity.</typeparam>
        /// <param name="tableName">Name of the table.</param>
        public void Register<TEntity>(String tableName)
        {
            m_TableNameLookup[typeof (TEntity)] = tableName;
        }

        /// <summary>
        /// Registers the specified table name.
        /// </summary>
        /// <param name="tableName">Name of the table.</param>
        /// <param name="entityType">Type of the entity.</param>
        public void Register(String tableName, Type entityType)
        {
            m_TableNameLookup[entityType] = tableName;
        }

        /// <summary>
        /// Sets the meta entity.
        /// </summary>
        /// <param name="entityType">Type of the entity.</param>
        /// <param name="metaEntity">The meta entity.</param>
        public void SetMetaEntity(Type entityType, PersistanceMetadata metaEntity)
        {
            m_MetaEntityLookup[entityType] = metaEntity;
        }

        #endregion

        #region Fields and Constants

        private readonly Dictionary<Type, PersistanceMetadata> m_MetaEntityLookup =
            new Dictionary<Type, PersistanceMetadata>();

        private readonly Dictionary<Type, RelationshipList> m_RelationshipLookup =
            new Dictionary<Type, RelationshipList>();

        private readonly Dictionary<Type, string> m_TableNameLookup = new Dictionary<Type, string>();

        #endregion

        #region Nested type: Relationship

        /// <summary>
        /// 
        /// </summary>
        public class Relationship
        {
            #region Public Instance Properties

            /// <summary>
            /// Gets or sets the child key field.
            /// </summary>
            /// <value>The child key field.</value>
            public string ChildKeyField { get; set; }

            /// <summary>
            /// Gets or sets the child reference field.
            /// </summary>
            /// <value>The child reference field.</value>
            public string ChildReferenceField { get; set; }

            /// <summary>
            /// Gets or sets the type of the child.
            /// </summary>
            /// <value>The type of the child.</value>
            public Type ChildType { get; set; }

            /// <summary>
            /// Gets or sets the parent key field.
            /// </summary>
            /// <value>The parent key field.</value>
            public string ParentKeyField { get; set; }

            /// <summary>
            /// Gets or sets the type of the parent.
            /// </summary>
            /// <value>The type of the parent.</value>
            public Type ParentType { get; set; }

            #endregion
        }

        #endregion

        #region Nested type: RelationshipList

        /// <summary>
        /// 
        /// </summary>
        public class RelationshipList : List<Relationship>
        {
        }

        #endregion
    }
}